#!/bin/bash

# Trap Signal for clean up
trap "cleanUp" EXIT

# Check cycle (seconds)
cycle=1

# Save all id of process created by launcher
pids=()
pcmds=()

# Create process and append id into pids
function pCreate() {
  "$@" &

  # Append last process id (the process created above) into pids
  pids[${#pids[*]}]=$!
  # Append command into pcmds
  pcmds[${#pcmds[*]}]="$*"

  echo "[$(date +%Y-%m-%d\ %H:%M:%S)] $* is created with pid $!"
}

# Kill process using pid
function pKill() {
  kill $1

  echo "[$(date +%Y-%m-%d\ %H:%M:%S)] ${pid}: ${pcmd} is killed"
}

# Restart process created by pCreate using pids or pcmds index
function pRestart() {
  # Get existing pcmd and pid using idx
  local pid
  local pcmd
  pid=${pids[$1]}
  pcmd=${pcmds[$1]}

  # Create new process using existing pcmd
  ${pcmd} &

  # Update pid
  pids[$1]=$!

  echo "[$(date +%Y-%m-%d\ %H:%M:%S)] ${pid}: ${pcmd} restarted with new pid $!"
}

# Check process is alive or not using pid
function pAliveCheck() {
  # Search for pid
  local result
  result="$(ps -ef | egrep -v "grep|tail|vi" | awk '{print $2}' | grep -w $1)"

  if [ -z "${result}" ]
  then
    echo "[$(date +%Y-%m-%d\ %H:%M:%S)] $1 is dead"
    return 0
  else
    echo "[$(date +%Y-%m-%d\ %H:%M:%S)] $1 is alive"
    return 1
  fi
}

# Clean up and exit launcher
function cleanUp() {
  echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Cleaning up"

  for pid in ${pids[*]}
  do
    pKill $pid
  done

  echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Clean-up is finished"

  exit 1
}

sudo modprobe v4l2loopback \
	devices=5 exclusive_caps=1,1,1,1,1 video_nr=3,4,10,11,12 \
	card_label="VirtualRearLeft","VirtualRearRight","VirtualInside","VirtualFront","VirtualRear"

# Test process
pCreate "./test.o" "pTest1"
pCreate "./test.o" "pTest2"
pCreate "./test.o" "pTest3"

# Third party services initialize
# pCreate "redis-server"
# pCreate "mysql"
# pCreate "v4l2loopback"

# iTour services initialize
# pCreate "detector-inside"
# pCreate "detector-front"
# pCreate "detector-rear"
# pCreate "decision"
# pCreate "data-processor"
# pCreate "nodejs"

# Check for alive or not every 1 second
while [ 1 ]
do
  echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Start to check"

  for idx in ${!pids[*]};
  do
    pid=${pids[$idx]}
    pcmd=${pcmds[$idx]}

    echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Checking pid ${pid}: ${pcmd}"

    pAliveCheck $pid

    if [ $? == 0 ]
    then
      pRestart $idx
    fi
  done

  echo "[$(date +%Y-%m-%d\ %H:%M:%S)] Sleep for ${cycle}s"
  sleep ${cycle}s
done
